package com.mantou.proxyadapter.pool;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeMap;

import com.mantou.proxyadapter.importer.DefaultImporter;
import com.mantou.proxyadapter.importer.Importer;

public class SourcePool {

	private TreeMap<String,Proxy> pool = new TreeMap<String, Proxy>();
	private Importer importer = new DefaultImporter();

	public SourcePool setImporter(Importer importer) {
		this.importer = importer;
		return this;
	}

	private SourcePool(){}

	private static SourcePool instance;
	public static SourcePool getInstance(){
		synchronized (SourcePool.class) {
			if(instance == null){
				instance = new SourcePool();
				instance.addProxy(instance.importer.newproxy(1024));
			}
		}
		return instance;
	}

	public Proxy get(String key){
		return pool.get(key);
	}

	public boolean addProxy(Proxy proxy){
		if(proxy == null || proxy.getIp() == null || !proxy.getIp().matches("\\d+(\\.\\d+){3}")){
			return false;
		}
		proxy.setKey(proxy.getIp() + proxy.getPort());
		pool.put(proxy.getKey(), proxy);
		return true;
	}

	public boolean addProxy(String proxy){
		if(proxy == null || !proxy.matches("\\d+(\\.\\d+){3}:\\d+")){
			return false;
		}
		String[] split = proxy.split(":");
		Proxy proxyobj = new Proxy(split[0], Integer.parseInt(split[1]));
		return addProxy(proxyobj);
	}

	public void addProxy(List<Proxy> proxys){
		for(Proxy proxy:proxys){
			addProxy(proxy);
		}
	}

	public int size(){
		return pool.size();
	}

	public void clear(){
		pool.clear();
	}

	public List<Proxy> get(final int num){
		List<Proxy> ret = new ArrayList<Proxy>();
		NavigableSet<String> descendingKeySet = pool.descendingKeySet();
		int i=0;
		for(String key:descendingKeySet){
			if(i>=num)
				return ret;
			ret.add(pool.get(key));
			i++;
		}
		final int j =i;
		new Thread(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
				addProxy(importer.newproxy(num -j));
			}

		}.start();
		return ret;
	}

	public void feedback(Collection<DomainPool.ProxyHolder> proxyholders){
		for(DomainPool.ProxyHolder holder:proxyholders){
			Proxy proxy = pool.get(holder.proxykey);
			if(proxy == null){
				continue;
			}
			int score = proxy.getScore();
			long newscore =0;
			if(holder.enable = false){
				score -=50;
			}else{
				newscore += 100 * holder.passrate;
				newscore += (3000 -holder.delay)/30;
				score *= 0.8;
				score += (newscore * 0.2);
			}
			proxy.setScore(score);
		}
	}
}
